﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using LimaLims.Application.Service.Role;
using LimaLims.Application.Service.Sys.Dto;
using LimaLims.Core;
using LimaLims.Core.Entity.Equipment;
using LimaLims.Core.Entity.System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Yitter.IdGenerator;

namespace LimaLims.Application.Service.Sys
{
    /// <summary>
    /// 用户站内信
    /// </summary>
    [ApiDescriptionSettings(Name = "SysMessage", Order = 173)]
    [Route("api")]
    public class SysMessageService : ISysMessageService, IDynamicApiController, ITransient
    {
        private readonly IRepository<SysMessage> _sysMessageRep;  // 用户站内信表仓储
        private readonly IRepository<MessageContent> _messageContentRep;  // 站内信内容表仓储
        private readonly ISysRoleService _sysRoleService;//角色服务接口

        public SysMessageService(IRepository<SysMessage> sysMessageRep, IRepository<MessageContent> messageContentRep, ISysRoleService sysRoleService)
        {
            _sysMessageRep = sysMessageRep;
            _messageContentRep = messageContentRep;
            _sysRoleService = sysRoleService;
        }

        /// <summary>
        /// 获取当前用户未读消息数量
        /// </summary>
        [NonAction]
        public async Task<int> GetUserMessageCount()
        {
            return await _sysMessageRep.DetachedEntities.CountAsync(u => u.ReceiveUserId == CurrentUserInfo.UserId && !u.IsRead);
        }

        /// <summary>
        /// 新增站内信
        /// </summary>
        [UnitOfWork, NonAction]
        public async Task AddSysMessage(AddSysMessageInput input)
        {
            var messsageContent = new MessageContent
            {
                Id = YitIdHelper.NextId(),
                Title = input.Title,
                Content = input.Content,
                ParamId = input.ParamId,
                Tag = input.Tag,
                Url = input.Url
            };

            await _messageContentRep.InsertNowAsync(messsageContent);

            //获取接收用户ID
            var userIds = await _sysRoleService.GetUsersByMenuPermission(input.Permission);

            if (userIds.Any())
            {
                List<SysMessage> messages = new List<SysMessage>();

                foreach (var userId in userIds)
                {
                    var sysmessage = new SysMessage
                    {
                        Id = YitIdHelper.NextId(),
                        ReceiveUserId = userId,
                        IsRead = false,
                        MessageContentId = messsageContent.Id,
                    };
                    messages.Add(sysmessage);
                }
                await _sysMessageRep.InsertAsync(messages);
            }

        }

        /// <summary>
        /// 删除单据
        /// </summary>
        [HttpPost("sysMessage/delete")]
        public async Task Delete(long id)
        {
            SysMessage message = await _sysMessageRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == id);
            if (message == null)
                throw Oops.Oh("不存在此数据");

            await message.DeleteAsync();
        }

        /// <summary>
        /// 设置已读未读
        /// </summary>
        [HttpPost("sysMessage/set")]
        public async Task Set(long id, bool isRead)
        {
            SysMessage message = await _sysMessageRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == id);
            if (message == null)
                throw Oops.Oh("不存在此数据");
            message.IsRead = isRead;

            await _sysMessageRep.UpdateIncludeAsync(message, new[] { nameof(SysMessage.IsRead) });
        }

        /// <summary>
        /// 用户站内信分页
        /// </summary>
        [HttpGet("sysMessage/page")]
        public async Task<PageResult<SysMessageOutput>> QueryPage([FromQuery] SysMessagePageInput input)
        {
            var sysNotices = await _sysMessageRep.DetachedEntities.Include(s => s.MessageContent)
                                         .Where(input.IsRead.HasValue, u => u.IsRead == input.IsRead)
                                         .Where(u => u.ReceiveUserId == CurrentUserInfo.UserId)
                                         .OrderByDescending(u => u.CreatedTime)
                                         .Select(u => new SysMessageOutput
                                         {
                                             Id = u.Id,
                                             Title = u.MessageContent.Title,
                                             Content = u.MessageContent.Content,
                                             IsRead = u.IsRead,
                                             ParamId = u.MessageContent.ParamId,
                                             Url = u.MessageContent.Url,
                                             Tag = u.MessageContent.Tag,
                                             CreatedTime = u.CreatedTime,
                                             CreatedUserName = u.CreatedUserName,
                                         }).ToADPagedListAsync(input.PageNo, input.PageSize);

            return sysNotices;
        }
    }
}
